"""
消息服务
"""

from typing import List, Dict, Any, Optional
from sqlalchemy.orm import Session
from sqlalchemy import and_, or_, desc
from datetime import datetime

from database import Message as MessageDB, MessageRead as MessageReadDB

class MessageService:
    """消息服务类"""
    
    def __init__(self, db: Session):
        self.db = db
    
    async def get_user_messages(
        self, 
        user_id: int, 
        message_type: Optional[str] = None,
        is_read: Optional[bool] = None,
        page: int = 1, 
        page_size: int = 20
    ) -> Dict[str, Any]:
        """获取用户消息列表"""
        
        # 构建查询
        query = self.db.query(MessageDB).filter(
            or_(
                MessageDB.receiver_id == user_id,
                MessageDB.receiver_id.is_(None)  # 系统广播消息
            )
        )
        
        if message_type:
            query = query.filter(MessageDB.message_type == message_type)
        
        # 如果指定了已读状态，需要关联查询
        if is_read is not None:
            if is_read:
                # 查询已读消息
                query = query.join(MessageReadDB).filter(
                    and_(
                        MessageReadDB.user_id == user_id,
                        MessageReadDB.message_id == MessageDB.id
                    )
                )
            else:
                # 查询未读消息
                read_message_ids = self.db.query(MessageReadDB.message_id).filter(
                    MessageReadDB.user_id == user_id
                ).subquery()
                query = query.filter(~MessageDB.id.in_(read_message_ids))
        
        # 分页
        total = query.count()
        messages = query.order_by(desc(MessageDB.created_at)).offset(
            (page - 1) * page_size
        ).limit(page_size).all()
        
        # 获取用户已读的消息ID
        read_message_ids = set(
            row[0] for row in self.db.query(MessageReadDB.message_id).filter(
                MessageReadDB.user_id == user_id
            ).all()
        )
        
        # 构造响应数据
        messages_data = []
        for msg in messages:
            messages_data.append({
                "id": msg.id,
                "title": msg.title,
                "content": msg.content,
                "message_type": msg.message_type,
                "priority": msg.priority,
                "sender_id": msg.sender_id,
                "is_read": msg.id in read_message_ids,
                "created_at": msg.created_at.isoformat() if msg.created_at else None
            })
        
        # 获取未读消息数量
        unread_count = await self.get_unread_count(user_id)
        
        return {
            "messages": messages_data,
            "total": total,
            "page": page,
            "page_size": page_size,
            "total_pages": (total + page_size - 1) // page_size,
            "unread_count": unread_count
        }
    
    async def mark_messages_read(self, user_id: int, message_ids: List[int]) -> None:
        """标记消息为已读"""
        for message_id in message_ids:
            # 检查是否已经标记为已读
            existing = self.db.query(MessageReadDB).filter(
                and_(
                    MessageReadDB.user_id == user_id,
                    MessageReadDB.message_id == message_id
                )
            ).first()
            
            if not existing:
                read_record = MessageReadDB(
                    user_id=user_id,
                    message_id=message_id,
                    read_at=datetime.now()
                )
                self.db.add(read_record)
        
        self.db.commit()
    
    async def get_unread_count(self, user_id: int) -> int:
        """获取未读消息数量"""
        # 获取用户可见的所有消息
        all_messages = self.db.query(MessageDB.id).filter(
            or_(
                MessageDB.receiver_id == user_id,
                MessageDB.receiver_id.is_(None)
            )
        ).subquery()
        
        # 获取已读消息
        read_messages = self.db.query(MessageReadDB.message_id).filter(
            MessageReadDB.user_id == user_id
        ).subquery()
        
        # 计算未读数量
        unread_count = self.db.query(all_messages.c.id).filter(
            ~all_messages.c.id.in_(read_messages)
        ).count()
        
        return unread_count
    
    async def delete_message(self, message_id: int, user_id: int) -> None:
        """删除消息（软删除，实际是标记为已删除）"""
        # 这里可以实现软删除逻辑
        # 或者删除用户的已读记录
        self.db.query(MessageReadDB).filter(
            and_(
                MessageReadDB.user_id == user_id,
                MessageReadDB.message_id == message_id
            )
        ).delete()
        
        self.db.commit()
    
    async def create_message(self, title: str, content: str, message_type: str, 
                           sender_id: Optional[int] = None, receiver_id: Optional[int] = None,
                           priority: str = "normal") -> Dict[str, Any]:
        """创建消息"""
        message = MessageDB(
            title=title,
            content=content,
            message_type=message_type,
            priority=priority,
            sender_id=sender_id,
            receiver_id=receiver_id
        )
        
        self.db.add(message)
        self.db.commit()
        self.db.refresh(message)
        
        return {
            "id": message.id,
            "title": message.title,
            "content": message.content,
            "message_type": message.message_type,
            "priority": message.priority,
            "created_at": message.created_at.isoformat() if message.created_at else None
        }